package tacticalLayer.tactics;

import org.jdom.Element;

import planninglanguage.conditions.Condition;
import planninglanguage.conditions.UnitTypeAtCondition;
import planninglanguage.plans.BasicOperatorPlan;
import planninglanguage.plans.BuildBOPlan;
import planninglanguage.plans.Plan;
import util.XMLWriter;
import base.WargusGameState;
import base.WargusStateImporter;
import base.WargusUnit;

public class BuildTactic extends Tactic {
	int m_state;
	BuildBOPlan m_goal;
	UnitTypeAtCondition m_arrival_cond = null;
	
	public BuildTactic(int unitID,int playerID,BuildBOPlan goal) {
		super(unitID);
		m_state = 0;
		m_goal = goal;
		m_arrival_cond = new UnitTypeAtCondition(WargusStateImporter.unitTypeToString(m_goal.getBuildType()),m_goal.getX(),m_goal.getY(), playerID);		
	}
	
	public BasicOperatorPlan getGoal() {
		return m_goal;
	}
	
	/*
	 * Returns the tactic to be executed in the next cycle ("null" means end of tactic)
	 */
	public Tactic cycle(WargusGameState gameState) {

		System.out.println("AttackTactic " + m_unitID + ": State " + m_state);

		switch(m_state) {
		case 0: // Issue the command:
				m_goal.send();
				m_state=1;

				
				System.out.println("BuildTactic " + m_unitID + ": sent to build...");
				return this;
		case 1: // Test if the unit is moving or just waiting... in case of waiting, send the command again:
				{
					WargusUnit u = gameState.getUnit(m_goal.getUnitID());
					if (WargusStateImporter.statusToString(u.getStatus()[0]).equals("idle")) m_state=0;
					if (m_arrival_cond.test(gameState)) return new IdleTactic(m_goal.getUnitID());
					return this;				
				}
		
		}
		
		return null;		
	}
	
	public void writeXML(XMLWriter w) {
		w.tag("tactic type=\"build\"");
		{
			w.tag("unit-id", m_unitID);
			w.tag("plan");
			{
				m_goal.writeXML(w);
			}
			w.tag("/plan");
			w.tag("state", m_state);
			m_arrival_cond.writeXML(w);
		}
		w.tag("/tactic");
	}
	
	protected static BuildTactic loadTacticFromXML(Element e) {
		assert e.getName().equals("tactic") :
			"BuildTactic.loadFromXML: Invalid XML Element " +	e.getName();
		assert e.getAttributeValue("type").equals("build") :
			"BuildTactic.loadFromXML: Invalid Tactic type " +	
			e.getAttributeValue("type");
		
		int unitID = Integer.parseInt(e.getChildText("unit-id"));
		BuildBOPlan plan = (BuildBOPlan) Plan.loadPlanFromXML(e.getChild("plan")); 
		
		// passing any playerID now but will be changed once we load the condition
		BuildTactic t = new BuildTactic(unitID, 0, plan);

		t.m_state = Integer.parseInt(e.getChildText("state"));
		t.m_arrival_cond = (UnitTypeAtCondition) Condition.loadFromXML(e.getChild("condition"));
		
		return t;
	}
}
